﻿#pragma once
#include <assert.h>
#include "reverse_iterator.h"
namespace sfw
{

    template<class T>
    class vector
    {
    public:
        typedef T* iterator;
        typedef const T* const_iterator;

        typedef Reverse_iterator<iterator, T&, T*> r_iterator;
        typedef Reverse_iterator<const_iterator, const T&, const T*> const_r_iterator;
        vector()
            :_start(nullptr)
            , _finish(nullptr)
            , _endofstorage(nullptr)
        {}
        vector(const vector<T>& e)
            :_start(nullptr)
            , _finish(nullptr)
            , _endofstorage(nullptr)
        {
            if (this != &e)
            {
                delete[] _start;
                _start = new T[e.capacity()];
                for (size_t i = 0; i < e.size(); i++)
                {
                    _start[i] = e._start[i];
                }
                _finish = _start + e.size();
                _endofstorage = _start + e.capacity();
            }
        }
        vector(size_t n, const T& t = T())
        {
            resize(n, t);
        }
        vector(int n, const T& t = T())
        {
            resize(n, t);
        }
        template<class inputiterator>
        vector(inputiterator st, inputiterator ed)
        {
            while (st != ed)
            {
                push_back(*st);
                ++st;
            }
        }
        void swap(vector<T>& v)
        {
            std::swap(_start, v._start);
            std::swap(_finish, v._finish);
            std::swap(_endofstorage, v._endofstorage);
        }
        vector<T>& operator=(vector<T> v)
        {
            swap(v);
            return *this;
        }
        ~vector()
        {

            delete[] _start;
            _start = nullptr;
            _finish = nullptr;
            _endofstorage = nullptr;
        }

        //iterator
        iterator begin()
        {
            return _start;
        }
        iterator end()
        {
            return _finish;
        }
        const_iterator begin() const
        {
            return _start;
        }
        const_iterator end() const
        {
            return _finish;
        }
        r_iterator rbegin()
        {
            return r_iterator(end());
        }
        r_iterator rend()
        {
            return r_iterator(begin());
        }
        const_r_iterator rbegin() const
        {
            return const_r_iterator(end());
        }
        const_r_iterator rend() const
        {
            return const_r_iterator(begin());
        }
        //size
        size_t size() const
        {
            return _finish - _start;
        }
        size_t capacity() const
        {
            return _endofstorage - _start;
        }
        void reserve(size_t n)
        {

            if (n > capacity())
            {
                size_t len = size();
                iterator tmp = new T[n];
                for (size_t i = 0; i < len; i++)
                {
                    tmp[i] = _start[i];
                }
                delete[] _start;
                _start = tmp;
                _finish = _start + len;
                _endofstorage = _start + n;
            }
        }
        void resize(size_t n, const T t = T())
        {
            if (n < size())
            {
                _finish = _start + n;
            }
            else
            {
                if (n > capacity()) reserve(n);
                for (iterator i = _finish; i < _start + n; i++)
                {
                    *i = t;
                }
                _finish = _start + n;
            }
        }
        //modify
        void push_back(const T& e)
        {
            //����
            if (_finish == _endofstorage)
            {
                size_t n = capacity() == 0 ? 4 : 2 * capacity();
                reserve(n);
            }
            //����
            *_finish = e;
            _finish++;
        }
        void insert(iterator pos, const T& t)
        {
            assert(pos >= _start && pos <= _finish);
            if (_finish == _endofstorage)
            {
                size_t n = capacity() == 0 ? 4 : 2 * capacity();
                reserve(n);
            }
            iterator end = _finish;
            while (end > pos)
            {
                *end = *(end - 1);
                --end;
            }
            *pos = t;
            _finish++;
        }
        //** erase�Ժ󣬵�����ʧЧ��vs�����˼��
        void erase(iterator pos)
        {
            assert(pos >= _start && pos < _finish);
            iterator it = pos;
            while (it < _finish)
            {
                *it = *(it + 1);
                it++;
            }
            _finish--;
        }
        iterator erase(iterator first, iterator last)
        {
            assert(first >= _start && first < _finish);
            assert(last >= _start && last <= _finish);
            assert(first <= last);
            iterator it = first;
            while (last != _finish)
            {
                *it = *last;
                ++it, ++last;
            }
            _finish = it;
            return it;
        }
    private:
        iterator _start = nullptr;
        iterator _finish = nullptr;
        iterator _endofstorage = nullptr;
    };

}
template<class T>
class vector
{
public:
    typedef T* iterator;
    typedef const T* const_iterator;

private:
    iterator start;
    iterator finish;
    iterator end_of_storage;
};
